﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Mani.Common.Security;
using Mani.Common;
using RastinArgham.CRM.Business;

namespace RastinArgham.CRM.Web
{

    /// <summary>
    /// 
    /// </summary>
    /// <remarks>
    /// Very Weird bug happening on the server regarding ViewState of GridView.Datakeys after PageIndexChange being Empty!
    /// http://forums.asp.net/t/1020478.aspx/1?GridView+DataKeys+Array+is+Empty
    /// http://www.google.com/search?q=GridView+DateKeys+Empty+after+page+index+change&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a#pq=gridview+datakeys.count++0&hl=en&cp=27&gs_id=3a&xhr=t&q=GridView+DataKeys+ViewState&qe=R3JpZFZpZXcgRGF0YUtleXMgVmlld1N0YXRl&qesig=6Gzp5qKFCtWGOR20mCazkg&pkc=AFgZ2tklQd7jOa5y4TiJg37cDyJibOgf0Y7I0wVc3ZDEmqvyq1xLMqRRCB84TX3pX4RmlJEgTOwX9fo4O1lcb8gRh_33WCh7Yg&pf=p&sclient=psy-ab&client=firefox-a&rls=org.mozilla:en-US%3Aofficial&source=hp&pbx=1&oq=GridView+DataKeys+ViewState&aq=f&aqi=&aql=&gs_sm=&gs_upl=&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=84c58f105e12c753&biw=1920&bih=880
    /// </remarks>
    public partial class users : System.Web.UI.Page
    {
        public ISecurityManager securityManager { get; set; }
        public CRMRepository crmRepo { get; set; }
        bool isAgent;
        Guid agentUserId;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (securityManager == null)
            {
                securityManager = new SecurityManager();
                securityManager.authProvider = new WebAuthorizationProvider();
            }

            if (crmRepo == null)
                crmRepo = new CRMRepository();

            bool hasAgentAccess = securityManager.IsActionPermitted("define_reseller");
            bool hasAdminAccess = securityManager.IsActionPermitted("user_management");

            if (!hasAgentAccess && !hasAdminAccess)
                Response.Redirect("~/access_denied.aspx");

            if (!hasAdminAccess && hasAgentAccess)
            {
                isAgent = true;
                agentUserId = securityManager.authProvider.GetCurrentUser().UserId;
            }

            if (!Page.IsPostBack)
            {
                LoadUsers();
                LoadRoles();
                LoadCities();
                LoadAgents();
            }
        }

        private void LoadRoles()
        {
            List<aspnet_Roles> roles = new List<aspnet_Roles>();
            if (isAgent)
            {
                roles.Add(securityManager.GetRoleByName("reseller"));
            }
            else
            {
                roles = securityManager.GetRoles();
            }

            cbUserRoles.DataSource = roles;
            cbUserRoles.DataBind();
        }

        private void LoadCities()
        {
            if (isAgent)
            {
                lbCities.DataSource = crmRepo.GetCitiesByUser(agentUserId);
            }
            else
            {
                lbCities.DataSource = crmRepo.GetCities();
            }

            lbCities.DataBind();
        }

        private void LoadUsers()
        {
            gvUsers.DataKeyNames = new string[] { "UserName" };

            if (isAgent)
            {
                gvUsers.DataSource = crmRepo.GetUsersByParent(agentUserId, txtSearch.Text);
            }
            else
            {
                gvUsers.DataSource = securityManager.GetUsers(txtSearch.Text);
            }
            gvUsers.DataBind();
        }

        private void LoadAgents()
        {
            List<aspnet_Users> agents = new List<aspnet_Users>();
            if (isAgent)
                agents.Add(securityManager.authProvider.GetCurrentUser());
            else
                agents = securityManager.FindUsersByRole("agents");

            ddlAgents.DataSource = agents;
            ddlAgents.DataBind();
        }

        protected void gvUsers_RowCreated(object sender, GridViewRowEventArgs e)
        {
            UIHelper.GridDeleteConfirm(e.Row);
        }

        protected void gvUsers_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {

            LoadUsers();

            string username = gvUsers.DataKeys[e.RowIndex].Value.ToString();
            securityManager.DeleteUser(username);
            LoadUsers();
            ClearForm();
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {

            if (txtUserName.ReadOnly)
                Update();
            else
                New();

            UIHelper.ClientAlert(this, "تغییرات با موفقیت ذخیره شد");
            UIHelper.ClientRedirect(this, "users.aspx");
        }

        private void Update()
        {
            aspnet_Users user = securityManager.GetUserInfo(txtUserName.Text);
            user.aspnet_Membership.Email = txtUserEmail.Text;
            user.aspnet_Membership.LoweredEmail = txtUserEmail.Text.ToLower();
            user.aspnet_Membership.IsLockedOut = cbIsLockedOut.Checked;
            user.aspnet_Membership.IsApproved = !cbIsLockedOut.Checked;

            if (!String.IsNullOrEmpty(txtPassword.Text))
                securityManager.UpdatePassword(user.UserName, txtPassword.Text);


            foreach (ListItem item in cbUserRoles.Items)
            {
                List<aspnet_Roles> roles = new List<aspnet_Roles>();
                roles.Add(securityManager.GetRoleByName(item.Text));

                if (item.Selected)
                {
                    if (!securityManager.IsUserinRole(user.UserName, item.Text))
                    {
                        securityManager.AddUserToRoles(user, roles);
                    }
                }
                else if (securityManager.IsUserinRole(user.UserName, item.Text))
                {
                    securityManager.RemoveUserFromRoles(user, roles);
                }
            }

            securityManager.SaveChanges();

            foreach (ListItem pItem in lbCities.Items)
            {
                if (pItem.Selected)
                {
                    crmRepo.AddUserToProvince(user.UserId, Convert.ToInt32(pItem.Value));
                }
                else
                {
                    crmRepo.DeleteUserFromCity(user.UserId, Convert.ToInt32(pItem.Value));
                }
            }

            if (ddlAgents.SelectedValue == "-1")
                crmRepo.SetUserParent(user.UserId, null);
            else
                crmRepo.SetUserParent(user.UserId, new Guid(ddlAgents.SelectedValue));

            crmRepo.Save();
        }

        private void New()
        {
            aspnet_Users alreadyExist = securityManager.GetUserInfo(txtUserName.Text);
            if (alreadyExist != null)
            {
                UIHelper.ClientAlert(this, "نام کاربری که انتخاب کردید قبلا به کاربر دیگری اختصاص یافته، لطفا نام کاربری جدیدی را انتخاب کنید");
                return;
            }

            aspnet_Users user = securityManager.CreateUser(txtUserName.Text, txtPassword.Text, txtUserEmail.Text);
            user.aspnet_Membership.IsLockedOut = cbIsLockedOut.Checked;

            List<aspnet_Roles> roles = new List<aspnet_Roles>();

            foreach (ListItem item in cbUserRoles.Items)
            {
                if (item.Selected)
                    roles.Add(securityManager.GetRoleByName(item.Text));
            }

            securityManager.AddUserToRoles(user, roles);
            securityManager.SaveChanges();

            foreach (ListItem pItem in lbCities.Items)
            {
                if (pItem.Selected)
                    crmRepo.AddUserToProvince(user.UserId, Convert.ToInt32(pItem.Value));
            }

            if (ddlAgents.SelectedValue != "-1")
                crmRepo.SetUserParent(user.UserId, new Guid(ddlAgents.SelectedValue));            

            crmRepo.Save();
        }

        protected void gvUsers_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
        {
            ClearForm();

            LoadUsers();

            DataKeyArray keys = gvUsers.DataKeys;

            Trace.Write("DataKeys Count: " + keys.Count.ToString());

            for (int i = 0; i < keys.Count; i++)
            {
                Trace.Write(i.ToString() + ": " + keys[i].Value);
            }

            Trace.Write("Selected Index: " + e.NewSelectedIndex.ToString());

            if (Trace.IsEnabled)
                return;

            string username = gvUsers.DataKeys[e.NewSelectedIndex].Value.ToString();
            aspnet_Users user = securityManager.GetUserInfo(username);

            txtUserName.Text = username;
            txtUserName.ReadOnly = true;
            txtUserEmail.Text = user.aspnet_Membership.Email;
            cbIsLockedOut.Checked = user.aspnet_Membership.IsLockedOut;

            foreach (var role in user.aspnet_Roles)
            {
                ListItem item = cbUserRoles.Items.FindByValue(role.RoleName);
                if (item != null)
                    item.Selected = true;
            }

            List<City> cities = crmRepo.FindCitiesByUser(user.UserId);
            foreach (var c in cities)
            {
                ListItem lItem = lbCities.Items.FindByValue(c.CityId.ToString());
                if (lItem != null)
                    lItem.Selected = true;
            }

            User u = crmRepo.GetUserById(user.UserId);
            if (u.ParentUserId.HasValue)
            {
                ListItem uItem = ddlAgents.Items.FindByValue(u.ParentUserId.ToString());
                if (uItem != null)
                    uItem.Selected = true;
            }
        }

        private void ClearForm()
        {
            txtPassword.Text = String.Empty;
            txtUserEmail.Text = String.Empty;
            txtUserName.Text = String.Empty;
            txtUserName.ReadOnly = false;
            cbUserRoles.ClearSelection();
            lbCities.ClearSelection();
            ddlAgents.ClearSelection();
            cbIsLockedOut.Checked = false;
        }

        protected void gvUsers_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            gvUsers.PageIndex = e.NewPageIndex;
            LoadUsers();
        }

        protected void btnSearch_Click(object sender, EventArgs e)
        {
            LoadUsers();
        }
    }
}